package com.itheima.filter;

import com.alibaba.fastjson.JSON;
import com.itheima.pojo.Result;
import com.itheima.utils.JwtUtils;
import io.jsonwebtoken.Claims;
import lombok.extern.slf4j.Slf4j;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
//@WebFilter("/*") //拦截所有
@Slf4j
public class LoginFilter implements Filter {
    /*
       拦截所有的请求 包括 登录 部门  员工  ...请求
       1:有没有哪个请求不需要校验令牌？
            登录例外 如果判断出来是登录就放行。
       2:拦截请求的时候，什么样情况才放行，能访问到资源？
            有令牌且令牌解析合法的( 不抛异常就是合法)
        否则 都返回      Result.error("NOT_LOGIN")---对象的json格式
     */
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
       /*
         ServletRequest 请求对象      HttpServletRequest
         ServletResponse 响应对象     HttpServletResponse
           有基于Http协议方法
        */
        //调用方法 前置条件  想使用子类特有方法 向下转型
        HttpServletRequest request = (HttpServletRequest) servletRequest;//请求
        HttpServletResponse response = (HttpServletResponse) servletResponse;//响应

        //1:获取请求路径
        String url = request.getRequestURL().toString();
        //2:判断当前 路径是不是 登录请求
        if(url.contains("/login")){//就来就是 登录请求 不用校验直接放行
            //放行
            filterChain.doFilter(request,response);
            //方法结束 不用继续了
            return;
        }
      //3:不是登录要 查看令牌  获取请求头上的 token令牌
        String token = request.getHeader("token");
        log.info("从请求头获取令牌:"+token);//token null  ""

        //4:如果令牌是 null 或者是 “” 字符串 没有必要校验 直接 让用户登录
        if(token==null || token.equals("")){
            log.info("token不存在！！");
            // 请它回去登录
            Result result = Result.error("NOT_LOGIN");
            // 怎么把result对象 转换成json并写给浏览器
            // 需要用到阿里巴巴 的fastjson 导依赖
            String jsonString = JSON.toJSONString(result);
            //响应到 浏览器上  通过
            response.setContentType("application/json;charset=utf-8");
            response.getWriter().write(jsonString);
            return;//不用放下 已经给你打回去！！
        }

        //5:有令牌 令牌不为空，校验令牌 解析令牌

        try{
            Claims claims = JwtUtils.parseJWT(token);
            //claims map集合里面存的 键值对数据 就是我们下发令牌存的数据  改天有用... 项目一有用
            log.info("令牌解析成功!");
        }catch (Exception e){
            log.info("令牌解析失败");
            // 请它回去登录
            Result result = Result.error("NOT_LOGIN");
            // 怎么把result对象 转换成json并写给浏览器
            // 需要用到阿里巴巴 的fastjson 导依赖
            String jsonString = JSON.toJSONString(result);
            //响应到 浏览器上  通过
            response.setContentType("application/json;charset=utf-8");
            response.getWriter().write(jsonString);
            return;//不用放下 已经给你打回去！！
        }

        //只要没return 说明到最后 有令牌 且解析成功
        //6:放行
        filterChain.doFilter(request,response);

    }
}
